import time
from openpyxl import load_workbook
from openpyxl import Workbook
import os
import config
from PySide2 import QtWidgets
from PySide2.QtUiTools import QUiLoader
from PySide2.QtWidgets import QTableWidgetItem,QProgressBar,QMessageBox
from PySide2.QtCore import Qt

# 电压\电流测试EXCEL类
class ExcelData:
    #  电压\电流测试 Excel 初始化创建
    def ExcelInit(self,Max,Min,SNLimit,TestMode,TestModel,DeviceID,BatchNo):
        # 文件名称
        self.TestModel = TestModel
        self.BatchNo = BatchNo
        if TestMode == 'V':
            self.addr = "D:\古鑫自耗电测试数据\电压测试\\"+self.BatchNo+'\\'  # 固定路径前缀

        elif TestMode=='C':
            self.addr = "D:\古鑫自耗电测试数据\电流测试\\"+self.BatchNo+'\\'  # 固定路径前缀

        elif TestMode == 'Diff':
            self.addr = "D:\古鑫自耗电测试数据\电压差测试\\"+self.BatchNo+'\\'  # 固定路径前缀

        self.systime = (time.strftime("%Y-%m-%d %H'%M'%S", time.localtime()))  # 文件时间
        self.FileName = self.addr  + self.TestModel + '  ' + self.systime +  ".xlsx"  # 合并后的文件名字

        # 实例化，创建一个Excel
        self.wb = Workbook()
        # 获得一个的工作表
        self.ws = self.wb.active
        # 修改列宽
        self.ws.column_dimensions['A'].width = 15.5
        self.ws.column_dimensions['B'].width = 9.5
        self.ws.column_dimensions['C'].width = 11.5
        self.ws.column_dimensions['D'].width = 21
        self.ws.column_dimensions['E'].width = 42.13


        if TestMode == 'V':
            # 插入表头
            self.ws.append(['序列号', '电压值(V)', '测试结果', '测试时间','当前设备编号'])
            # 键入用户输入的参数
            self.ws.cell(2, 1, ("SN长度限制:%s") % SNLimit)
            self.ws.cell(2, 2, ("Max:%sV") % Max)
            self.ws.cell(3, 2, ("Min:%sV") % Min)
            self.ws.cell(2, 5, ("%s") % DeviceID)

        elif TestMode=='C':
            # 插入表头
            self.ws.append(['序列号', '电流值(μA)', '测试结果', '测试时间'])
            # 键入用户输入的参数
            self.ws.cell(2, 2, ("Max:%sμA") % Max)
            self.ws.cell(3, 2, ("Min:%sμA") % Min)
            self.ws.cell(2, 1, ("SN长度限制:%s") % SNLimit)

        elif TestMode=='Diff':
            # 插入表头
            self.ws.append(['序列号', '前电压(V)','后电压（V）','电压差值','压差判定结果', '压差测试时间'])
            # 键入用户输入的参数
            self.ws.cell(2, 2, ("Max:%sV") % Max)
            self.ws.cell(3, 2, ("Min:%sV") % Min)

            self.ws.cell(2, 4, ("Max:%smV") % Max)
            self.ws.cell(3, 4, ("Min:%smV") % Min)

            self.ws.cell(2, 1, ("SN长度限制:%s") % SNLimit)

        if not os.path.exists(self.addr):
            os.makedirs(self.addr)
            self.wb.save(filename=self.FileName)
        else:
            self.wb.save(filename=self.FileName)

        return self.FileName

    # 修改已经存在的表
    def DataSver(self,ui,FileName,row,col,Data):
        try:
            # 传入参数依次为：带路径的文件名称、对应行、对应列、需要修改的数据
            wb2 = load_workbook(FileName)
            worksheet = wb2.worksheets[0]
            worksheet.cell(row,col,Data)
            wb2.save(filename=FileName)
        except PermissionError: #Excel被打开了
            QtWidgets.QMessageBox.critical(ui, "写入异常", "# 写入的Excel被打开了，请关闭否则无法写入！ #\n# 关闭后需要重新测试该SN号 #")

    # 删除对应的行
    def Delete_row(self,FileName,row):

        wb2 = load_workbook(FileName)
        worksheet = wb2.worksheets[0]
        worksheet.delete_rows(row)  # 表示删除表格的第一行
        wb2.save(FileName)

# 电压差EXCEL类
class ExcelDataDiff(ExcelData):
    def __init__(self,Max,Min,SNLimit,TestMode,TestModel,DifMax,DifMin,SetDifTimeMax,SetDifTimeMin,DeviceID,BatchNo):
        super().__init__()
        self.Max = Max #电压上限
        self.Min = Min #电压下限
        self.SNLimit = SNLimit #SN长度
        self.TestMode = TestMode #测试类型 电压差类型
        self.TestModel = TestModel #测试型号
        self.DifMax = DifMax #压差上限
        self.DifMin = DifMin #压差下限
        self.SetDifTimeMax = SetDifTimeMax #静置时间上限
        self.SetDifTimeMin = SetDifTimeMin #静置时间下限
        self.DeviceID = DeviceID #设备ID
        self.BatchNo = BatchNo
    #电压差表初始化（重写了父类）
    def ExcelInit(self):
        #如果为电压差测试
        if self.TestMode == 'Diff':
            self.addr = "D:\古鑫自耗电测试数据\电压差测试\\"+self.BatchNo+'\\'  # 固定前缀

        self.systime = (time.strftime("%Y-%m-%d %H'%M'%S", time.localtime()))  # 文件时间
        self.FileName = self.addr + self.TestModel + '  ' + self.systime +  ".xlsx"  # 合并后的文件名字

        # 实例化
        self.wb = Workbook()
        # 激活 worksheet
        self.ws = self.wb.active

        # 修改列宽
        self.ws.column_dimensions['A'].width = 15.5
        self.ws.column_dimensions['B'].width = 9.5
        self.ws.column_dimensions['C'].width = 11.5
        self.ws.column_dimensions['D'].width = 9.88
        self.ws.column_dimensions['E'].width = 12.38
        self.ws.column_dimensions['F'].width = 21
        self.ws.column_dimensions['G'].width = 21
        self.ws.column_dimensions['H'].width = 18.63
        self.ws.column_dimensions['I'].width = 42.13

        if self.TestMode=='Diff':
            # 插入表头
            self.ws.append(['序列号', '前电压(V)','后电压（V）','电压差值','压差判定结果', '前电压测试时间','后电压测试时间','已静置时间（小时）','设备编号检查'])

            # 键入用户输入的参数
            self.ws.cell(2, 1, ("SN长度限制:%s") % self.SNLimit)

            self.ws.cell(2, 3, ("Max:%sV") % self.Max)
            self.ws.cell(3, 3, ("Min:%sV") % self.Min)

            self.ws.cell(2, 4, ("Max:%smV") % self.DifMax)
            self.ws.cell(3, 4, ("Min:%smV") % self.DifMin)

            self.ws.cell(2, 8, ("静置时间上限%s") % self.SetDifTimeMax)
            self.ws.cell(3, 8, ("静置时间下限%s") % self.SetDifTimeMin)

            self.ws.cell(2, 9, ("%s") % self.DeviceID)
        if not os.path.exists(self.addr):
            os.makedirs(self.addr)
            self.wb.save(filename=self.FileName)
        else:
            self.wb.save(filename=self.FileName)

        return self.FileName

    # 数据对比
    def Contrast(FirstVoltage, LastVoltage, standard):
        VolDiff = FirstVoltage - LastVoltage
        if VolDiff <= standard:
            return True

# 记录已经存在的SN信息
class SnData:
    def __init__(self,FileName):
        self.FileName = FileName
        self.excel = ExcelData()

    # 功能：记录测试过的SN号，EXCEL的行号，储存到的字典中
    def save_sn(self,sn,row):
        SnDic = {}
        SnDic['sn'] = sn
        SnDic['row'] = row

        return SnDic

    # 查询SN是否在EXCEL中，如果有则删除
    def sn_judeg(self,sn,list):
        SnDic = {}
        lens=len(list)

        for i in range(len(list[:-1])):

            if sn == list[i]['sn'] :
                # 删除对应的行和列表元素，并更新EXCEL坐标
                self.excel.Delete_row(self.FileName,list[i]['row'])
                config.change_excel_row_value(config.get_excel_row_value()-1)
                # 显示循环次数
                for j in range((lens-i)-1):
                    list[i+j+1]['row'] = list[i+j+1]['row'] - 1
                del list[i]

                return True

        return False

# 功能：查找EXCEL文件内的SN号，并将对应的数据输出
def econtent(FileName, query):
    # 查找原则：1、只输出合格SN
    #         2、当出现多个SN号时，输出最后一个SN号
    # FileName：指明查找的位置，带绝对路径的文件名
    # query：需要查找的字符串
    # return：返回一个value_arr数组，将指明是否找到和对应的数据
    wb = load_workbook(FileName) #打开Excel
    sheets = wb.sheetnames       #工作名字列表
    flag = 0  # 找到了几个对应的数据
    list_value = []  # 所有合格
    # 查找到的数据集合
    value_arr = {'flag': False,  # 是否找到
                'sn': None,  # 对应的SN号
                'voltage': None,  # 电压值
                'test': None,  # 测试结果
                'time': None}  # 测试时间

    for name in sheets:
        sheet = wb.active
        for r in range(1, sheet.max_row + 1):
            v = sheet.cell(row=r, column=1)
            if v.value == query:    #如果在该行找到了，再进行数据采集
                for c in range(1, sheet.max_column + 1):
                    if v.value == query:    # 是否找到
                        value_arr['flag'] = True
                        value_arr['sn'] = v.value  # 对应的SN号

                        v = sheet.cell(row=r, column=c + 1)
                        value_arr['voltage'] = v.value  # 电压值

                        v = sheet.cell(row=r, column=c + 2)
                        value_arr['test'] = v.value  # 测试结果

                        v = sheet.cell(row=r, column=c + 3)
                        value_arr['time'] = v.value  # 测试时间

                        if value_arr['test'] == 'PASS':
                            flag += 1
                            list_value.append(value_arr.copy())
                        elif value_arr['test'] == 'FULL':
                            return False

    if value_arr['flag'] == False:# 没有找到则返回原数组，flag=False
        return False
    else:
        return list_value[flag - 1]#找到则返回对应的内容

# 往UI和EXCEL中写入测试内容
def ui_excel_write(ui,text):
    # 初始化类
    send_excel_data = ExcelData()

    # 获取UI表格行、列，并写入内容
    row = config.get_row_value()
    col = config.get_col_value()
    item = QTableWidgetItem()
    item.setText(text)
    item.setTextAlignment(Qt.AlignCenter)  # 文本居中
    ui.TestData.setItem(row, col, item)

    # 获取Excel表格行列，并写入内容
    excel_row = config.get_excel_row_value()
    excel_col = config.get_excel_col_value()
    excel_name = config.get_excel_name_value()
    send_excel_data.DataSver(ui,excel_name, excel_row, excel_col, text)

    # 更新UI、Excel列的全局变量
    config.change_col_value(col + 1)
    config.change_excel_col_value(excel_col + 1)

# 只往UI中写入测试内容
def ui_write(ui,text):

    # 获取UI表格行、列，并写入内容
    row = config.get_row_value()
    col = config.get_col_value()
    item = QTableWidgetItem()
    item.setText(text)
    item.setTextAlignment(Qt.AlignCenter)  # 文本居中
    ui.TestData.setItem(row, col, item)

    # 更新UI、Excel列的全局变量
    config.change_col_value(col + 1)

# 删除对应的行
def delete_row(FileName,row):
    wb2 = load_workbook(FileName)
    worksheet = wb2.worksheets[0]
    worksheet.delete_rows(row)  # 表示删除表格的第一行
    wb2.save(FileName)

# 读取excel中所有的SN号，并输出成列表
def rede_excel_sn_list(ui,FileName):
    progressBar = QProgressBar(ui)
    progressBar.resize(300, 20)
    progressBar.move(80, 30)

    wb = load_workbook(FileName)  # 打开Excel
    sheets = wb.sheetnames  # 工作名字列表
    flag = 0  # 找到了几个对应的数据
    excel_sn_list = []  # 所有合格
    # 查找到的数据集合
    value_arr = {'sn': None,  # 对应的SN号
                 'voltage': None,  # 电压值
                 'test': None,  # 测试结果
                 'time': None}  # 测试时间
    sheet = wb.active
    progressBar.setRange(0, sheet.max_row)  #设置进度条，进度数量

    for r in range(4, sheet.max_row + 1): #在表中的每一行中遍历
        v = sheet.cell(row=r, column=1) #取对应的SN号
        progressBar.setValue(r) # 设置进度值

        v = sheet.cell(row=r, column=1)  # 取对应的SN号
        value_arr['sn'] = v.value  # 放入SN号

        v = sheet.cell(row=r, column= 2)
        value_arr['voltage'] = v.value  # 电压值


        v = sheet.cell(row=r, column= 3)
        value_arr['test'] = v.value  # 测试结果


        v = sheet.cell(row=r, column= 4)
        value_arr['time'] = v.value  # 测试时间

        # flag += 1
        excel_sn_list.append(value_arr.copy())

    return excel_sn_list  # 找到则返回对应的内容

# 在列表中搜索SN和内容
def seek_sn(sn,list):
    flag = 0
    list_value=[]
    for i in range(len(list)):
        if list[i]['sn'] == sn:
            list_value.append(list[i])
            flag+=1
    return list_value[flag-1]
